//
//  QuickTable.swift
//  QZWM_User_new
//
//  Created by youai on 2019/4/24.
//  Copyright © 2019年 youi. All rights reserved.
//

import Foundation
import UIKit
import MJRefresh
import RxSwift
import RxCocoa

private let _QuickTableView_CellStr = "QuickTableView_CellStr"

///简化的Tabel类，可以只写一个Cell类就铺在界面上
class QuickTableView<T,C:QuickTableCellView<T>> : UITableView,UITableViewDelegate,UITableViewDataSource {
    var list = [T]()
    init(){
        super.init(frame: CGRect.zero, style: .plain)
        self.dataSource = self
        self.delegate = self
        self.register(C.self, forCellReuseIdentifier: _QuickTableView_CellStr)
        self.separatorStyle = .none
        self.backgroundColor = .clear
    }
    
    var onSetCell : ((C)->())? = nil
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return list.count
    }
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat{
        let index = indexPath[1]
        if index >= list.count || index < 0{
            return 0
        }
        let height = C.heightOf(list[index])
        let adjust = C.heightAdjust(index: index, listCount: list.count)
        return height + adjust
    }
    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return self.tableView(tableView, heightForRowAt: indexPath)
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell_ = self.dequeueReusableCell(withIdentifier: _QuickTableView_CellStr, for: indexPath)
        let cell = cell_ as! C
        let index = indexPath[1]
        onSetCell?(cell)
        cell.setData(list[index],at:index,listCount: list.count)
        return cell
    }
    
    var onDataSelected : ((T)->())? = nil
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
        onDataSelected?(list[indexPath[1]])
    }
    
    ///获取顶部下拉刷新组件
    private func getRefreshHeader()->MJRefreshHeader{
        if self.mj_header == nil {
            let header = MJRefreshNormalHeader()
            self.mj_header = header
            header.lastUpdatedTimeLabel.isHidden = true
            header.setTitle("下拉刷新...", for: .pulling)
            header.setTitle("下拉更新中...", for: .refreshing)
            header.setTitle("下拉刷新...", for: .willRefresh)
            header.setTitle("下拉刷新...", for: .idle)
            header.setTitle("没有了.", for: .noMoreData)
            header.setRefreshingTarget(self, refreshingAction: #selector(onHeaderRequery))
//                header.ignoredScrollViewContentInsetTop = iphoneX_EdgeInsetsPatch()*0.65 + 14
        }
        return self.mj_header!
    }
    ///顶部下拉刷新的信号源
    lazy var headerRequerySubject : PublishSubject<Void> = {
        _ = self.getRefreshHeader()
        return PublishSubject()
    }()
    @objc private func onHeaderRequery(){
        getRefreshFooter().state = .idle
        headerRequerySubject.onNext(())
    }
    ///用于顶部下拉的刷新功能实现，可处理已到最后页的状态
    func reloadForHeaderRequery(list:[T],isLastPage:Bool){
        _ = getRefreshHeader()
        _ = getRefreshFooter()
        self.list = list
        if !Thread.current.isMainThread {
            mainQueueAsync {
                self.reloadData()
                self.mj_header.endRefreshing()
                if isLastPage{
                    self.mj_footer.state = .noMoreData
                }
            }
            return
        }
        self.reloadData()
        self.mj_header.endRefreshing()
        if isLastPage{
            self.mj_footer.state = .noMoreData
        }else{
            self.mj_footer.state = .idle
        }
    }
    
    ///获取底部上拉加载更多组件
    private func getRefreshFooter()->MJRefreshFooter{
        if self.mj_footer == nil {
            let footer = MJRefreshAutoNormalFooter()
            footer.isOnlyRefreshPerDrag = true
            self.mj_footer = footer
            footer.setTitle("努力加载中...", for: .pulling)
            footer.setTitle("努力加载中...", for: .refreshing)
            footer.setTitle("努力加载中...", for: .willRefresh)
            footer.setTitle("", for: .idle)
            footer.setTitle("", for: .noMoreData)
            footer.setRefreshingTarget(self, refreshingAction: #selector(onFooterLoadMore))
        }
        return self.mj_footer!
    }
    ///底部上拉加载更多的信号源
    lazy var footerLoadMoreSubject : PublishSubject<Void> = {
        _ = self.getRefreshFooter()
        return PublishSubject()
    }()
    @objc private func onFooterLoadMore(){
        footerLoadMoreSubject.onNext(())
    }
    ///用于底部上拉加载更多刷新功能实现，可处理已到最后页的状态
    func reloadForFooterLoadMore(list:[T],isLastPage:Bool){
        self.list = list
        if !Thread.current.isMainThread {
            mainQueueAsync {
                self.reloadData()
                if isLastPage {
                    self.mj_footer.endRefreshingWithNoMoreData()
                }else{
                    self.mj_footer.endRefreshing()
                }
            }
            return
        }
        self.reloadData()
        if isLastPage {
            self.mj_footer.endRefreshingWithNoMoreData()
        }else{
            self.mj_footer.endRefreshing()
        }
    }
    
    //关闭所有刷新状态
    func resetRefreshState(){
        if let header = self.mj_header {
            if header.state != .idle {
               header.endRefreshing()
                header.state = .idle
            }
        }
        if let footer = self.mj_footer {
            if footer.state != .idle {
                footer.endRefreshing()
                footer.state = .idle
            }
        }
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

class QuickTableCellView<T> : UITableViewCell {
    
    func setData(_ data:T, at index:Int, listCount: Int){
        self.backgroundColor = .clear
        self.selectionStyle = .none
        fatalError("not implement")
    }
    class func heightOf(_ data:T)->CGFloat{
        fatalError("not implement")
    }
    class func heightAdjust(index:Int,listCount:Int)->CGFloat{
        return 0
    }
}



class QuickTableCellWithInit<T> : QuickTableCellView<T>{
    private var initFlag = false
    func initCell(container:UIView){
        fatalError("not implement")
    }
    
    func fillCell(_ data:T, at index:Int){
        fatalError("not implement")
    }
    
    var data : T? = nil
    override func setData(_ data:T, at index:Int, listCount:Int){
        if !initFlag{
            self.backgroundColor = .clear
            self.selectionStyle = .none
            initCell(container: contentView)
            initFlag = true
        }
        self.data = data
        fillCell(data, at:index)
    }
}

class QuickTableCellWithInitAndListCount<T> : QuickTableCellView<T>{
    private var initFlag = false
    func initCell(container:UIView){
        fatalError("not implement")
    }
    
    func fillCell(_ data:T, at index:Int, listCount:Int){
        fatalError("not implement")
    }
    
    var data : T? = nil
    override func setData(_ data:T, at index:Int, listCount:Int){
        if !initFlag{
            self.backgroundColor = .clear
            self.selectionStyle = .none
            initCell(container: contentView)
            initFlag = true
        }
        self.data = data
        fillCell(data, at:index, listCount: listCount)
    }
}
